"""
@project: vcat
@author: kang 
@github: https://github.com/fsksf 
@since: 2021/3/2 8:37 AM
"""
from typing import Callable, Dict, List, Set
from datetime import datetime, time
from pytz import timezone
from copy import copy
import traceback
from dataclasses import dataclass

from vcat.interface import BaseGateway
from vcat.utils.api_util import as_gateway
from vcat.core.constant import (
    Direction,
    Offset,
    DataLevel,
    ContractType,
    Currency,
    Exchange,
    OrderStatus,
    OptionType
)
from vcat.core.obj import (
    PositionData,
    ContractData,
    OrderData,
    TickData,
    BarData,
    OrderRequest,
    SubscribeRequest,
    CancelRequest,
)
from vcat.server.obj import DivMetaInfo, TagMetaInfo, MetaObj
from vcat.core.event import EventType, Event


@as_gateway
class BacktestGateway(BaseGateway):
    gateway_name = 'BacktestBroker'
    gateway_name_cn = '回测接口'

    @dataclass
    class ConfigSetting(MetaObj):
        account: str = 'backtest-1'

        @classmethod
        def meta(cls):
            _meta = DivMetaInfo(
                name='Backtest',
                title='Backtest-Broker',
                headers=[
                    TagMetaInfo(name='账号', field='account', value=cls.account),
                ]
            )
            return _meta.to_dict()

    def __init__(self, engine):
        super(BacktestGateway, self).__init__(engine)

    def init(self):
        from tests.data.contract import contract_info_df

        for _, ser in contract_info_df.iterrows():
            code, ex = ser['symbol'].split('.')
            contract = ContractData(
                code=code,
                exchange=Exchange(ex),
                contract_type=ContractType[ser['type']],
                name=ser['name'],
                lot_size=ser['lot_size'],
                min_volume=ser['min_volume'],
                price_tick=ser['price_tick'],
                broker_name='BacktestBroker'
            )
            print(contract)
            self.on_contract(contract)

    def login(self, params):
        self.init()
        return True

    def feed_bars(self, contract_ids: List[str], start_dt=None, end_dt=None, freq=DataLevel.minute):
        self.engine.guard_left.get_history_bar(contract_ids=contract_ids,
                                               start_dt=start_dt,
                                               end_dt=end_dt,
                                               freq=freq)

    def subscribe(self, contract_list: List[ContractData]):
        pass

    def send_order(self, req: OrderRequest) -> List[OrderData]:
        pass

    def cancel_order(self, order_id):
        pass

    def on_bar(self, bar: BarData):
        self.engine.guard_left.put(Event(event_type=EventType.BAR, data=bar))

    def query_account(self):
        pass

    def query_order(self):
        pass

    def query_position(self):
        pass
